var downloadUtil = require("download.js")
var bleUtils = require('ble-utils.js');
var util = require("util.js");
var commonUtil = require('../../common/common.js');
var ConstantData = require('../../common/constant_data.js')
var _getVerCallback = null;
var upgradeLogType = 50000;


function connectDfuDevice(device,getVerCallback) {
  if (getApp().globalData.isBeforeLeaseUpgrade) {
    wx.showLoading({
      title: '设备升级..',
      mask: true
    });
  }
  _getVerCallback = getVerCallback;
  bleUtils.createBLEConnection({
    deviceId: device.deviceId,
    timeOut: 5000
  }).then(function (res) {
    bleUtils.stopBluetoothDevicesDiscovery({})
    return bleUtils.getBLEDeviceServices({
      deviceId: device.deviceId
    })
  }).then(function (res) {
    console.log("设备的服务信息upgrade", res);
    //获取1530的服务
    for (var i = 0; i < res.services.length; i++) {
        var uuid = res.services[i]["uuid"]
        if (uuid.indexOf("00001530") != -1) {
          console.log("upgrade服务uuid-->", uuid);
          device.server1530 = res.services[i]
        }
    }

    return bleUtils.getBLEDeviceCharacteristics({//获取服务1530对应的特征值1531和1532
      deviceId: device.deviceId,
      serviceId: device.server1530["uuid"]
    })
  }).then(function (res) {
    console.log("获取特征码信息")
    for (var i in res.characteristics) {
      var c = res.characteristics[i]
      if (c.uuid.indexOf("00001531") != -1) {//00001531-1212-EFDE-1523-785FEABCD123
        device.characteristic1531 = c
      }
      if (c.uuid.indexOf("00001532") != -1) {//00001532-1212-EFDE-1523-785FEABCD123
        device.characteristic1532 = c
      }
    }
    return bleUtils.notifyBLECharacteristicValueChange({//开启1531的notify
      deviceId: device.deviceId,
      serviceId: device.server1530["uuid"],
      characteristicId: device.characteristic1531["uuid"],
      state: true
    })
  }).then(function (res) {
    console.log("进入升级模式")
    callback(device);
    return bleWriteTo1531(device, "0104")//向1531写入0104进入升级模式
  }).then(function (res) {
    console.log("开始传输bin文件")
    let arrayBuffer = new ArrayBuffer(12)
    let int32Array = new Uint32Array(arrayBuffer);
    let length = downloadUtil.dfuPackage.binData.byteLength//解压zip包后的bin文件长度
    int32Array[2] = length
    //向1532写入bin包长，固件会给手机发送消息
    // return bleWriteTo1532(device, util.hexFromBuffer(arrayBuffer))
    setTimeout(function(){
      return bleWriteTo1532(device, util.hexFromBuffer(arrayBuffer))
    },200)
  })
}

//点击界面的时候解压zip包，分别得到三个文件：.bin.dat和json文件，分别读取三个文件，拿到对应的buffer并返回存起来，上面写入bin文件的长度就是对应解压后的bin的buffer.byteLength 详细解压请查看官方api unzip
//向1531写入数据
function bleWriteTo1531(device, data) {
  data = util.bufferFromHex(data)
  return bleUtils.writeBLECharacteristicValue({
    deviceId: device.deviceId,
    serviceId: device.server1530["uuid"],
    characteristicId: device.characteristic1531["uuid"],
    value: data
  })
}

//向1532写入数据
function bleWriteTo1532(device, data) {
  console.log("bleWriteTo1532..",data);
  if (typeof (data) == 'string') {
    data = util.bufferFromHex(data)
  }
  return bleUtils.writeBLECharacteristicValue({
    deviceId: device.deviceId,
    serviceId: device.server1530["uuid"],
    characteristicId: device.characteristic1532["uuid"],
    value: data
  })
}

//收到固件传来的信息处理，开启notify后，向1531写入信息后，固件会传回信息
function callback(device) {
  bleUtils.onBLECharacteristicValueChange(function (res) {//固件信息回调
    let hexValue = util.hexFromBuffer(res.value)//将信息转为16进制
    if (hexValue == '100101') {//上面写入0104之后会有这个回调
      //向1531写入0200
      bleWriteTo1531(device, '0200').then(function (res) {
        //向1532写入.dat文件（14字节）
        let hexString = util.hexFromBuffer(downloadUtil.dfuPackage.datData)
        return bleWriteTo1532(device, hexString)
      }).then(function (res) {
        //向1531写入0201
        return bleWriteTo1531(device, "0201")
      })
    } else if (hexValue == '100201') {
      //向1531写入03
      bleWriteTo1531(device, "03").then(function (res) {
        console.log(res)
        //向1532写入bin文件大小，注意分包写，有两种方法可以分包，下面单独解释
        bleWriteBinFile(device, downloadUtil.dfuPackage, 0)

      })
    } else if (hexValue == '100301') {
      //向1531写入04
      bleWriteTo1531(device, "04").then(function (res) {
        console.log(res)
      })
    } else if (hexValue == '100401') {
      //写入05
      bleWriteTo1531(device, "05").then(function (res) {

      })
    }
  })
}  


function bleWriteBinFile(device, dfuPackage, offset) {
  let start = offset
  let length = dfuPackage.binData.byteLength
  for (; offset < length; offset = offset + 20) {

    let step = offset + 20 > length ? length - offset : 20
    let uint8Array = new Uint8Array(dfuPackage.binData, offset, step)
    let hex = ""
    for (let i in uint8Array) {
      let num = uint8Array[i];
      if (num < 16) {
        hex += '0'
      }
      hex += num.toString(16)
    }
    console.log("write bin cycle:", hex, offset)
    if(!hex){
      return;
    }
    let targetData = util.bufferFromHex(hex)
    wx.writeBLECharacteristicValue({
      deviceId: device.deviceId,
      serviceId: device.server1530["uuid"],
      characteristicId: device.characteristic1532["uuid"],
      value: targetData,
      fail: function (err) {
        offset = offset - 20//失败了重写一遍
        console.log('write bin fail', err);
      }
    })

    let percentage = (offset + step) / length
    percentage = (percentage * 100).toFixed(1)
    if (getApp().globalData.isBeforeLeaseUpgrade) {
        wx.showLoading({
          title: '更新' + percentage + '%',
          mask: true
        });
    }
    
    getApp().globalData._that.setData({
      upgradePercent:'(' + percentage + '%)'
    })

    if (!getApp().globalData._that.data.upgradeConnected) {
      console.log("蓝牙断开连接")
      getApp().globalData._that.setData({
        loading_show: false
      })
      break;
    }

    if (offset + step == length) {      
      console.log("升级完成");
      getApp().globalData._that.data.upgradeSuc = '升级成功！';     
      getApp().globalData._that.setData({
        loading_show: false
      })
      getApp().hideLoading();
      commonUtil.recordErrorInfo(ConstantData.CONSTATNT_DATA.LOG_TYPE_UPGRADE_DRIVE_SUC, "升级成功:" + getApp().globalData.upgradeMac, getApp().globalData.upgradeMac);
      if (_getVerCallback != null) {
        _getVerCallback();
      }
      if (getApp().globalData.isBeforeLeaseUpgrade)  {
        //租赁前升级完成重新连接进行租赁
        wx.showLoading({
          title: '租赁中...',
        })
        setTimeout(function(){
          getApp().hideLoading();
          getApp().globalData._that.executeConnect(getApp().globalData.upgradeScanMacRes);
        },500);
        
      }
      getApp().globalData.isBeforeLeaseUpgrade = false;
      break;
    }
    if (offset - start == 20) {
      setTimeout(function (res) {
        bleWriteBinFile(device, dfuPackage, offset + 20)
      }, 35);
      console.log("定时器间隔写入...")
      return;
    }
  }
}



//由于蓝牙每次发送只能传输20字节，所以在发送bin文件时候要分包，下面介绍两种方案：
//方法1：通过循环一直往固件写数据
// function bleWriteBinFile(device, dfuPackage, offset) {
//   let start = offset
//   let length = dfuPackage.binData.byteLength
//   for (; offset < length; offset = offset + 20) {

//     let step = offset + 20 > length ? length - offset : 20
//     let uint8Array = new Uint8Array(dfuPackage.binData, offset, step)
//     let hex = ""
//     for (let i in uint8Array) {
//       let num = uint8Array[i];
//       if (num < 16) {
//         hex += '0'
//       }
//       hex += num.toString(16)
//     }
//     console.log("write bin cycle:",hex,offset)
//     let targetData = util.bufferFromHex(hex)
//     wx.writeBLECharacteristicValue({
//       deviceId: device.deviceId,
//       serviceId: device.server1530["uuid"],
//       characteristicId: device.characteristic1532["uuid"],
//       value: targetData,
//       fail: function (err) {
//         offset = offset - 20//失败了重写一遍
//         console.log('write bin fail', err);
//       }
//     })
  
//     let percentage = (offset + step) / length
//     percentage = (percentage * 100).toFixed(1)
//     wx.showLoading({
//       title: '写入' + percentage + '%',
//       mask: true
//     })

//     if (offset + step == length) {
//       wx.showToast({
//         title: '写入完成',
//       })
//       console.log("升级完成");
//       break;
//     }
//     if (offset - start == 1000) {
//       setTimeout(function (res) {
//         bleWriteBinFile(device, dfuPackage, offset + 20)
//       }, 300);
//       console.log("定时器间隔写入...")
//       return;
//     }
//   }
// }


//方法2：用递归写入，成功之后写入下个数据，适合数据量不是很大时调用
// function bleWriteBinFile(device, dfuPackage, offset) {
//   let start = offset
//   let length = dfuPackage.binData.byteLength

//   let step = offset + 20 > length ? length - offset : 20
//   let uint8Array = new Uint8Array(dfuPackage.binData, offset, step)
//   let hex = ""
//   for (let i in uint8Array) {
//     let num = uint8Array[i];
//     if (num < 16) {
//       hex += '0'
//     }
//     hex += num.toString(16)
//   }
//   console.log("写入bin数据:" + offset,hex,offset)
//   let targetData = util.bufferFromHex(hex)

//   wx.writeBLECharacteristicValue({
//     deviceId: device.deviceId,
//     serviceId: device.server1530["uuid"],
//     characteristicId: device.characteristic1532["uuid"],
//     value: targetData,
//     fail: function (err) {//失败了重新写入
//       console.log('write bin fail', err)
//       bleWriteBinFile(device, dfuPackage, offset)
//       // setTimeout(function(){//部分Android机需要延时写入

//       // },250)
//     },
//     success: function () {
//       offset = offset + 20//成功了之后写入下一条数据
//       if (offset < length) {
//         bleWriteBinFile(device, dfuPackage, offset)
//       }
//       // setTimeout(function() {部分Android机需要延时写入

//       // }, 250)
//     }
//   })

//   let percentage = (offset + step) / length

//   percentage = (percentage * 100).toFixed(1)
//   wx.showLoading({
//     title: '写入' + percentage + '%',
//     mask: true
//   })
  
//   if (offset + step == length) {
//       wx.showToast({
//         title: '写入完成',
//       });
//   }
// }

module.exports = {
  connectDfuDevice: connectDfuDevice
}